package com.zx.idc.backend.gui.sys;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.zx.idc.backend.gui.common.BaseApi;
import com.zx.idc.backend.gui.common.Result;
import com.zx.idc.backend.gui.common.util.NetworkUtil;
import com.zx.idc.backend.gui.shiro.TokenManagerUtil;
import com.zx.idc.common.ref.copy.BeanCopyUtil;
import com.zx.idc.common.util.PasswordDigestUtil;
import com.zx.idc.ds.sys.entity.SysUser;
import com.zx.idc.ds.sys.entity.SysUserRole;
import com.zx.idc.ds.sys.service.ISysUserRoleService;
import com.zx.idc.ds.sys.service.ISysUserService;
import com.zx.idc.ds.sys.vo.SysUserVo;
import com.zx.idc.ds.tlog.service.ITLogSecurityService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统管理员信息管理 前端控制器
 * </p>
 *
 * @author rxliuli
 * @since 2019-01-31
 */
@RestController
@RequestMapping("/api/sysUser")
public class SysUserController extends BaseApi {
    @Autowired
    private ISysUserService service;
    @Autowired
    private ITLogSecurityService tlogSecurityService;
    @Autowired
    private TokenManagerUtil tokenManagerUtil;
    @Autowired
    private ISysUserRoleService sysUserRoleService;

    @GetMapping("/select-list")
    @RequiresPermissions(value = {"system-configuration:sys-user", "illegal-monitoring:mo-illegal-info"}, logical = Logical.OR)
    public Result<List<SysUser>> selectList() {
        return success(service.listForAll().stream().map(su -> su.setPassword(null)).collect(Collectors.toList()));
    }

    /**
     * 最近添加的count位管理员
     * @param count 查询数
     * @return
     */
    @GetMapping("/list-by-last-count/{count}")
    @RequiresPermissions("system-configuration:sys-user")
    public Result<List<SysUser>> listByLastCount(@PathVariable String count) {
        final List<SysUser> sysUserList = service.selectList(
            new EntityWrapper<>(new SysUser())
                .orderDesc(Collections.singleton("createTime"))
                .last("limit " + count)
        );
        final List<Integer> userIdList = sysUserList.stream().map(SysUser::getId).collect(Collectors.toList());
        final Map<Integer, Integer> sysUserRoleMap = sysUserRoleService.selectList(new EntityWrapper<SysUserRole>().in("userId", userIdList)).stream()
            .collect(Collectors.toMap(SysUserRole::getUserId, SysUserRole::getId, (id, id2) -> id));
        return success(sysUserList.stream().map(su -> BeanCopyUtil.copy(su, new SysUserVo()).exec().get()
            .setSysUserRoleId(sysUserRoleMap.get(su.getId()))
            .setSysUserRoleList(sysUserRoleService.selectList(new SysUserRole().setUserId(su.getId())))
            .setPassword(null))
            .collect(Collectors.toList()));
    }

    @GetMapping("/count")
    @RequiresPermissions("system-configuration:sys-user")
    public Result<Integer> count(SysUser sysUser) {
        return success(service.selectCount(new EntityWrapper<>(sysUser)));
    }

    @GetMapping("query-page")
    @RequiresPermissions("system-configuration:sys-user")
    public Result<Page<SysUser>> pageByParam(Page<SysUser> page, SysUser entity) {
        final Wrapper<SysUser> wrapper = new EntityWrapper<>();
        if (StringUtils.isNotEmpty(entity.getLoginName())) {
            wrapper.like("loginName", entity.getLoginName());
        }
        if (entity.getUserType() != null) {
            wrapper.eq("userType", entity.getUserType());
        }
        final Page<SysUser> sysUserPage = service.selectPage(page, wrapper);
        final List<Integer> userIdList = sysUserPage.getRecords().stream().map(SysUser::getId).collect(Collectors.toList());
        final Map<Integer, Integer> sysUserRoleMap = sysUserRoleService.selectList(new EntityWrapper<SysUserRole>().in("userId", userIdList)).stream().collect(Collectors.toMap(SysUserRole::getUserId, SysUserRole::getId, (id, id2) -> id));
        sysUserPage.setRecords(sysUserPage.getRecords().stream()
            .map(su -> BeanCopyUtil.copy(su, new SysUserVo()).exec().get().setSysUserRoleId(sysUserRoleMap.get(su.getId()))
                .setSysUserRoleList(sysUserRoleService.selectList(new SysUserRole().setUserId(su.getId()))))
            .collect(Collectors.toList()));
        return success(sysUserPage);
    }

    @PostMapping("/update")
    @RequiresPermissions("system-configuration:sys-user:edit")
    public Result<Boolean> update(@RequestBody SysUserVo entity) {
        return success(service.updateUser(entity));
    }

    @PostMapping("/add")
    @RequiresPermissions("system-configuration:sys-user:edit")
    public Result<Boolean> add(@RequestBody SysUserVo entity, HttpServletRequest request) {
        if (service.exists(new SysUser().setLoginName(entity.getLoginName()))) {
            return error("用户名已存在");
        }
        entity.setCreateTime(LocalDateTime.now())
            .setLastLoginTime(LocalDateTime.now())
            .setLoginSource(NetworkUtil.getIpAddress(request))
            .setStatus(SysUser.STATUS_ENABLE)
            .setPassword(PasswordDigestUtil.generateWithSalt(entity.getPassword()));
        return success(service.addUser(entity));
    }

    /**
     * 通用的删除方法
     *
     * @param id 实体主键
     * @return 删除是否成功，需要以 {@link Result#getData()} 作为判断标准
     */
    @PostMapping("/delete/{id}")
    @RequiresPermissions("system-configuration:sys-user:edit")
    public Result<Boolean> delete(@PathVariable("id") Long id) {
        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put("userId",id);
        return success(service.deleteById(id.intValue()) && sysUserRoleService.deleteByMap(columnMap));
    }

    @GetMapping("/get-user-menu/{userId}")
    @RequiresPermissions("system-configuration:sys-user")
    public Result<SysUserVo> get(@PathVariable Integer userId) {
        return success(service.getUserMenuByUserId(userId));
    }

    @PostMapping("/update-user-menu")
    @RequiresPermissions("system-configuration:sys-user:edit")
    public Result<Boolean> updateSysMenu(@RequestBody SysUserVo sysUserVo) {
        return success(service.updateUserMenu(sysUserVo));
    }
}

